home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP09.ZIP / CHAP09 / PATRON / TENANT.CPP < prev    next >
C/C++ Source or Header  |  1993-06-23  |  38KB  |  1,531 lines

  1. /*
  2.  * TENANT.CPP
  3.  * Modifications for Chapter 9
  4.  *
  5.  * Implementation of the CTentant class which holds information
  6.  * for a single object on a page.  It maintains position, references
  7.  * to data, and a storage.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19. #include "patron.h"
  20.  
  21.  
  22. /*
  23.  * CTenant::CTenant
  24.  * CTenant::~CTenant
  25.  *
  26.  * Constructor Parameters:
  27.  *  dwID            DWORD identifier for this page.
  28.  *  hWnd            HWND of the pages window.
  29.  *  pPG             LPCPages to the parent structure.
  30.  */
  31.  
  32. CTenant::CTenant(DWORD dwID, HWND hWnd, LPCPages pPG)
  33.     {
  34.     m_hWnd=hWnd;
  35.     m_dwID=dwID;
  36.  
  37.     m_fInitialized=0;
  38.     m_pIStorage=NULL;
  39.     m_cOpens=0;
  40.  
  41.     m_pObj=NULL;
  42.     m_pPG =pPG;
  43.  
  44.     //CHAPTER9MOD
  45.     m_cRef=0;
  46.     m_pIOleObject=NULL;
  47.     m_pIViewObject=NULL;
  48.  
  49.     m_pIOleClientSite=NULL;
  50.     m_pIAdviseSink=NULL;
  51.     //End CHAPTER9MOD
  52.     return;
  53.     }
  54.  
  55.  
  56. CTenant::~CTenant(void)
  57.     {
  58.     //CHAPTER9MOD
  59.     if (NULL!=m_pIViewObject)
  60.         {
  61.         m_pIViewObject->SetAdvise(m_fe.dwAspect, 0, NULL);
  62.         m_pIViewObject->Release();
  63.         }
  64.  
  65.     if (NULL!=m_pIOleObject)
  66.         m_pIOleObject->Release();
  67.  
  68.     //We delete our own interfaces since we control them
  69.     if (NULL!=m_pIAdviseSink)
  70.         delete m_pIAdviseSink;
  71.  
  72.     if (NULL!=m_pIOleClientSite)
  73.         delete m_pIOleClientSite;
  74.     //End CHAPTER9MOD
  75.  
  76.     if (NULL!=m_pObj)
  77.         {
  78.         //We know we only hold one reference from UCreate or FLoad
  79.         m_pObj->Release();
  80.         m_pObj=NULL;
  81.         }
  82.  
  83.     return;
  84.     }
  85.  
  86.  
  87.  
  88.  
  89. //CHAPTER9MOD
  90. /*
  91.  * CTenant::QueryInterface
  92.  * CTenant::AddRef
  93.  * CTenant::Release
  94.  *
  95.  * Purpose:
  96.  *  IUnknown members for CTenant object.
  97.  */
  98.  
  99. STDMETHODIMP CTenant::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  100.     {
  101.     *ppv=NULL;
  102.  
  103.     //Any interface on this object is the object pointer.
  104.     if (IsEqualIID(riid, IID_IUnknown))
  105.         *ppv=(LPVOID)this;
  106.  
  107.     if (IsEqualIID(riid, IID_IOleClientSite))
  108.         *ppv=(LPVOID)m_pIOleClientSite;
  109.  
  110.     if (IsEqualIID(riid, IID_IAdviseSink))
  111.         *ppv=(LPVOID)m_pIAdviseSink;
  112.  
  113.     /*
  114.      * If we actually assign an interface to ppv we need to AddRef it
  115.      * since we're returning a new pointer.
  116.      */
  117.     if (NULL!=*ppv)
  118.         {
  119.         ((LPUNKNOWN)*ppv)->AddRef();
  120.         return NOERROR;
  121.         }
  122.  
  123.     return ResultFromScode(E_NOINTERFACE);
  124.     }
  125.  
  126.  
  127. STDMETHODIMP_(ULONG) CTenant::AddRef(void)
  128.     {
  129.     return ++m_cRef;
  130.     }
  131.  
  132. STDMETHODIMP_(ULONG) CTenant::Release(void)
  133.     {
  134.     ULONG           cRefT;
  135.  
  136.     cRefT=--m_cRef;
  137.  
  138.     if (0L==m_cRef)
  139.         delete this;
  140.  
  141.     return cRefT;
  142.     }
  143.  
  144. //End CHAPTER9MOD
  145.  
  146.  
  147.  
  148.  
  149.  
  150. /*
  151.  * CTenant::GetID
  152.  *
  153.  * Return Value:
  154.  *  DWORD           dwID field in this tenant.  This function is only here
  155.  *                  to avoid hiding inline implementations in pages.h
  156.  */
  157.  
  158. DWORD CTenant::GetID(void)
  159.     {
  160.     return m_dwID;
  161.     }
  162.  
  163.  
  164.  
  165.  
  166.  
  167. /*
  168.  * CTenant::GetStorageName
  169.  *
  170.  * Parameters:
  171.  *  pszName         LPSTR to a buffer in which to store the storage name
  172.  *                  for this tenant.
  173.  *
  174.  * Return Value:
  175.  *  UINT            Number of characters stored.
  176.  */
  177.  
  178. UINT CTenant::GetStorageName(LPSTR pszName)
  179.     {
  180.     return wsprintf(pszName, "Tenant %lu", m_dwID);
  181.     }
  182.  
  183.  
  184.  
  185.  
  186.  
  187. /*
  188.  * CTenant::UCreate
  189.  *
  190.  * Purpose:
  191.  *  Creates a new tenant of the given CLSID, which can be either a
  192.  *  static bitmap or metafile now (Chapter 7) and which may eventually
  193.  *  be any OLE object.
  194.  *
  195.  * Parameters:
  196.  *  tType           TENANTTYPE to create, either a static metafile, bitmap,
  197.  *                  or some kind of OLE object (later chapters)
  198.  *                  This determined which OleCreate* call we use.
  199.  *  pvType          LPVOID providing the relevant pointer from which
  200.  *                  to create the tenant, depending on iType.
  201.  *  pFE             LPFORMATETC specifying the type of renderings to use.
  202.  *  pptl            LPPOINTL in which we can store offset coordinates.
  203.  *  pszl            LPSIZEL where this object should store its lometric extents.
  204.  *  pIStorage       LPSTORAGE of the page we live in.  We have to
  205.  *                  create another storage under this for the tenant.
  206.  *  ppo             LPPATRONOBJECT containing placement data.
  207.  *  dwData          DWORD containing extra data, sensitive to iType.
  208.  *
  209.  * Return Value:
  210.  *  UINT            A UCREATE_* value depending on what we actually do.
  211.  */
  212.  
  213. UINT CTenant::UCreate(TENANTTYPE tType, LPVOID pvType, LPFORMATETC pFE
  214.     , LPPOINTL pptl, LPSIZEL pszl, LPSTORAGE pIStorage
  215.     , LPPATRONOBJECT ppo, DWORD dwData)
  216.     {
  217.     HRESULT             hr;
  218.     LPUNKNOWN           pObj;
  219.     UINT                uRet=UCREATE_GRAPHICONLY;
  220.  
  221.     if (NULL==pvType || NULL==pIStorage)
  222.         return UCREATE_FAILED;
  223.  
  224.     //Fail if this is called for an already living tenant.
  225.     if (m_fInitialized)
  226.         return UCREATE_FAILED;
  227.  
  228.     m_fInitialized=TRUE;
  229.  
  230.     //Create a new storage for this tenant.
  231.     if (!FOpen(pIStorage))
  232.         return UCREATE_FAILED;
  233.  
  234.     /*
  235.      * Get the placement info if it's here.  We either have a non-NULL
  236.      * LPPATRONOBJECT in ppo or we have to use default placement and
  237.      * retrieve the size from the object itself.
  238.      */
  239.     pszl->cx=0;
  240.     pszl->cy=0;
  241.  
  242.     if (NULL!=ppo)
  243.         {
  244.         *pFE=ppo->fe;
  245.         *pptl=ppo->ptl;
  246.         *pszl=ppo->szl;     //Could be 0,0 in which case we ask object
  247.  
  248.         uRet=UCREATE_PLACEDOBJECT;
  249.         }
  250.  
  251.     hr=ResultFromScode(E_FAIL);
  252.  
  253.     //Now create an object based specifically for the type.
  254.     switch (tType)
  255.         {
  256.         case TENANTTYPE_NULL:
  257.             break;
  258.  
  259.         case TENANTTYPE_STATIC:
  260.             /*
  261.              * We could use OleCreateStaticFromData here which does
  262.              * pretty much what we're doing below.  However, it does
  263.              * not allow us to control whether we paste a bitmap or
  264.              * a metafile--it uses metafile first, bitmap second.  For
  265.              * this reason we'll use code developed in Chapter 6's
  266.              * FreeLoader to affect the paste.
  267.              */
  268.             hr=CreateStatic((LPDATAOBJECT)pvType, pFE, &pObj);
  269.             break;
  270.  
  271.         //CHAPTER9MOD
  272.         case TENANTTYPE_EMBEDDEDOBJECT:
  273.             hr=OleCreate(*((LPCLSID)pvType), IID_IUnknown, OLERENDER_DRAW
  274.                 , NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  275.             break;
  276.  
  277.         case TENANTTYPE_EMBEDDEDFILE:
  278.             hr=OleCreateFromFile(CLSID_NULL, (LPSTR)pvType, IID_IUnknown
  279.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  280.             break;
  281.  
  282.         case TENANTTYPE_EMBEDDEDOBJECTFROMDATA:
  283.             hr=OleCreateFromData((LPDATAOBJECT)pvType, IID_IUnknown
  284.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  285.             break;
  286.         //End CHAPTER9MOD
  287.  
  288.         default:
  289.             break;
  290.         }
  291.  
  292.     //If creation didn't work, get rid for the element FOpen created.
  293.     if (FAILED(hr))
  294.         {
  295.         Destroy(pIStorage);
  296.         return UCREATE_FAILED;
  297.         }
  298.  
  299.     //CHAPTER9MOD
  300.     //We don't get the size if PatronObject data was seen already.
  301.     FObjectInitialize(pObj, pFE, dwData);
  302.  
  303.     //We depend here on m_pIOleObject having been initialized.
  304.     if ((0==pszl->cx && 0==pszl->cy))
  305.         {
  306.         SIZEL   szl;
  307.  
  308.         //Try to get the real size of the object, default to 2"*2"
  309.         SETSIZEL((*pszl), 2*LOMETRIC_PER_INCH, 2*LOMETRIC_PER_INCH);
  310.  
  311.         if (SUCCEEDED(m_pIOleObject->GetExtent(pFE->dwAspect, &szl)))
  312.             {
  313.             /*
  314.              * Protect ourselves from OLE 1.0 servers that did MM_HIMETRIC
  315.              * instead of HIMETRIC units, thus had a negative y extent.
  316.              */
  317.             if (0 > szl.cy)
  318.                 szl.cy=